package view;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MapView.LayoutParams;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.passby.R;

import data.PassByItem;

public class PassByOverLay<Item extends OverlayItem> extends CustomItemizedOverlay<PassByOverlayItem> {

	private MapView mapView;
	private MapBubbleItem<PassByOverlayItem> balloonView;
	private Hashtable<String, MapBubbleItem<PassByOverlayItem>> balls;
	private View clickRegion;
	private int viewOffset;
	final MapController mc;
	private ArrayList<PassByOverlayItem> m_overlays = new ArrayList<PassByOverlayItem>();
	private Context c;
	
	/**
	 * Create a new BalloonItemizedOverlay
	 * 
	 * @param defaultMarker - A bounded Drawable to be drawn on the map for each item in the overlay.
	 * @param mapView - The view upon which the overlay items are to be drawn.
	 */
	public PassByOverLay(Drawable defaultMarker, MapView mapView) {
		super(boundCenterBottom(defaultMarker),mapView);
		this.mapView = mapView;
		viewOffset = 0;
		balls = new Hashtable<String, MapBubbleItem<PassByOverlayItem>>();
		mc = mapView.getController();
		c = mapView.getContext();
	}
	
	/**
	 * Set the horizontal distance between the marker and the bottom of the information
	 * balloon. The default is 0 which works well for center bounded markers. If your
	 * marker is center-bottom bounded, call this before adding overlay items to ensure
	 * the balloon hovers exactly above the marker. 
	 * 
	 * @param pixels - The padding between the center point and the bottom of the
	 * information balloon.
	 */
	public void setBalloonBottomOffset(int pixels) {
		viewOffset = pixels;
	}
	public int getBalloonBottomOffset() {
		return viewOffset;
	}

	/**
	 * Expose map view to subclasses.
	 * Helps with creation of balloon views. 
	 */
	protected MapView getMapView() {
		return mapView;
	}
	
	/**
	 * Sets the visibility of this overlay's balloon view to GONE. 
	 */
	@Override
	protected void hideBalloon() {
		if (balloonView != null) {
			balloonView.setVisibility(View.GONE);
		}
	}
	
	@Override
	protected boolean onTap(int index) {
		
//		currentFocussedIndex = index;
		currentFocussedItem = createItem(index);
//		
		createAndDisplayBalloonOverlay(currentFocussedItem);
		
		mc.animateTo(currentFocussedItem.getPoint());
		
		return true;
	}
	
	/**
	 * Hides the balloon view for any other BalloonItemizedOverlay instances
	 * that might be present on the MapView.
	 * 
	 * @param overlays - list of overlays (including this) on the MapView.
	 */
	private void hideOtherBalloons(List<Overlay> overlays) {
		
		for (Overlay overlay : overlays) {
			if (overlay instanceof PassByOverLay<?> && overlay != this) {
				((PassByOverLay<?>) overlay).hideBalloon();
			}
		}
	}
	
	@Override
	protected boolean createAndDisplayBalloonOverlay(PassByOverlayItem item){
		balloonView = createBalloonOverlayView();
		clickRegion = (View) balloonView.findViewById(R.id.user_info_inner_layout);
		clickRegion.setOnTouchListener(createBalloonTouchListener());
	
		balloonView.setVisibility(View.GONE);
		
		balloonView.setLayerItem(item);
		
		GeoPoint point = item.getPoint();
		MapView.LayoutParams params = new MapView.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, point,
				MapView.LayoutParams.BOTTOM_CENTER);
		params.mode = MapView.LayoutParams.MODE_MAP;
		
		balloonView.setVisibility(View.VISIBLE);
		
		balloonView.setLayoutParams(params);
		mapView.addView(balloonView);
		balls.put(item.user.username,balloonView);
		return true;
	}
	
	public void update(PassByItem item)
	{
		balloonView = balls.get(item.user.username);
		balloonView.setData(item);
		balloonView.setVisibility(View.VISIBLE);
		MapView.LayoutParams params = new MapView.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, item.location,
				MapView.LayoutParams.BOTTOM_CENTER);
		params.mode = MapView.LayoutParams.MODE_MAP;
		balloonView.setLayoutParams(params);
	}
	
	public void addOverlay(PassByOverlayItem overlay) {
	    m_overlays.add(overlay);
	    populate();
	    createAndDisplayBalloonOverlay(overlay);
	}

	@Override
	protected PassByOverlayItem createItem(int i) {
		return m_overlays.get(i);
	}

	@Override
	public int size() {
		return m_overlays.size();
	}

	@Override
	protected boolean onBalloonTap(int index, PassByOverlayItem item) {
		Toast.makeText(c, "onBalloonTap for overlay index " + index,
				Toast.LENGTH_LONG).show();
		Intent intent=new Intent();
		intent.setClass(c,ItemDetailView.class);
		Bundle bundle=new Bundle();
		bundle.putSerializable("item", currentFocussedItem.mImageURL);
		intent.putExtras(bundle);
		c.startActivity(intent);
		return true;
	}

	protected MapBubbleItem<PassByOverlayItem> createBalloonOverlayView() {
		// use our custom balloon view with our custom overlay item type:
		return new MapBubbleItem<PassByOverlayItem>(getMapView().getContext(), getBalloonBottomOffset());
	}
}
